#pragma once

#include <nlohmann/json.hpp>
#include <string>
#include <functional>
#include <map>
#include <fstream>
#include <regex>
#include <vector>

namespace SimpleRest {

using namespace nlohmann;

// HTTP方法枚举
enum class HttpMethod {
    GET,
    POST,
    PUT,
    DELETE
};

// HTTP请求结构体
struct HttpRequest {
    HttpMethod method;
    std::string uri;
    json body;
    std::map<std::string, std::string> headers;
    std::map<std::string, std::string> params; // 用于存储动态路由参数
};

// HTTP响应结构体
struct HttpResponse {
    int status_code;
    json body;
    std::map<std::string, std::string> headers;
};

// RESTful API处理器类
class RestApiHandler {
public:
    using HandlerFunction = std::function<HttpResponse(const HttpRequest&)>;

    // 添加路由处理器
    void addRoute(const std::string& uri, HttpMethod method, HandlerFunction handler) {
        std::string key = methodToString(method) + " " + uri;
        route_handlers[key] = handler;
        uri_patterns[key] = convertUriToPattern(uri);
        route_params[key] = extractParams(uri);
    }

    // 持久化存储数据到文件
    void saveDataToFile(const std::string& filename, const json& data) {
        std::ofstream file(filename);
        file << data.dump(4);
        file.close();
    }

    // 从文件加载数据
    json loadDataFromFile(const std::string& filename) {
        json data;
        std::ifstream file(filename);
        if (file.is_open()) {
            file >> data;
            file.close();
        }
        return data;
    }

    // 处理HTTP请求
    HttpResponse handleRequest(const HttpRequest& request) {
        for (const auto& entry : route_handlers) {
            const std::string& key = entry.first;
            const HandlerFunction& handler = entry.second;
            const std::string& pattern = uri_patterns[key];
            const auto& params = route_params[key];

            std::smatch match;
            if (std::regex_match(request.uri, match, std::regex(pattern))) {
                // 提取动态参数
                HttpRequest new_request = request;
                for (size_t i = 0; i < params.size(); ++i) {
                    new_request.params[params[i]] = match[i + 1].str();
                }
                return handler(new_request);
            }
        }
        return createResponse(404, "Route not found");
    }

    // 测试API
    HttpResponse testRoute(HttpMethod method, const std::string& uri, const json& body = json::object()) {
        HttpRequest request;
        request.method = method;
        request.uri = uri;
        request.body = body;
        return handleRequest(request);
    }

private:
    std::map<std::string, HandlerFunction> route_handlers;
    std::map<std::string, std::string> uri_patterns;
    std::map<std::string, std::vector<std::string>> route_params;

    std::string methodToString(HttpMethod method) {
        switch (method) {
            case HttpMethod::GET: return "GET";
            case HttpMethod::POST: return "POST";
            case HttpMethod::PUT: return "PUT";
            case HttpMethod::DELETE: return "DELETE";
            default: return "UNKNOWN";
        }
    }

    std::string convertUriToPattern(const std::string& uri) {
        std::string pattern = uri;
        std::regex param_regex(R"(<([^>]+)>)");
        pattern = std::regex_replace(pattern, param_regex, R"(([^/]+))");
        return "^" + pattern + "$";
    }

    std::vector<std::string> extractParams(const std::string& uri) {
        std::vector<std::string> params;
        std::regex param_regex(R"(<([^>]+)>)");
        std::smatch matches;
        std::string::const_iterator searchStart(uri.cbegin());
        while (std::regex_search(searchStart, uri.cend(), matches, param_regex)) {
            params.push_back(matches[1].str());
            searchStart = matches.suffix().first;
        }
        return params;
    }

    HttpResponse createResponse(int status_code, const json& body = json::object()) {
        HttpResponse response;
        response.status_code = status_code;
        response.body = body;
        response.headers["Content-Type"] = "application/json";
        return response;
    }
};

} // namespace SimpleRest